package com.bkck.sharkblockade.levels.harpoon;

import com.bkck.sharkblockade.levels.paddle.Paddle;
import com.bkck.sharkblockade.levels.shark.Shark;
import com.bkck.sharkblockade.levels.shark.SharkDeath;
import android.graphics.Bitmap;
import android.graphics.Canvas;

/**
 * Harpoon powerup.
 * 
 * @author Team BKCK
 * 
 */
public class Harpoon {
  
  // the speed of the harpoon
  private float pixelsPerMeter = 10;
  // time of last update in milliseconds
  private long lastUpdateTime = -1;
  // image bitmap
  private Bitmap bitmap;
  // dimension
  private int harpoonHeight;
  private int harpoonWidth;
  // coordinates
  private float x;
  private float y;
  private float previousY;
  // speed of harpoon
  private float yVelocity;
  // whether this harpoon was launched
  private boolean launched;
  // on launch harpoon when we have it.
  private boolean powerupObtained;

  /**
   * Harpoon Constructor.
   * 
   * @param bitmap The bitmap image.
   */
  public Harpoon(Bitmap bitmap) {
    this.bitmap = bitmap;
    this.harpoonHeight = bitmap.getHeight();
    this.harpoonWidth = bitmap.getWidth();
    this.x = -50;
    this.y = -50;
    this.yVelocity = 0;
    this.powerupObtained = false;
    this.launched = false;

  }

  /**
   * Empty constructor to be called by Activities.
   */
  public Harpoon() {

  }

  /**
   * Return the last update time.
   * 
   * @return The last update time.
   */
  public long getLastUpdateTime() {
    return lastUpdateTime;
  }

  /**
   * Set the last update time.
   * 
   * @param lastUpdateTime
   */
  public void setLastUpdateTime(long lastUpdateTime) {
    this.lastUpdateTime = lastUpdateTime;
  }

  /**
   * Return the bitmap.
   * 
   * @return The bitmap.
   */
  public Bitmap getBitmap() {
    return bitmap;
  }

  /**
   * Set bitmap and it's width and height.
   * 
   * @param bitmap
   */
  public void setBitmap(Bitmap bitmap) {
    this.bitmap = bitmap;
    this.harpoonHeight = bitmap.getHeight();
    this.harpoonWidth = bitmap.getWidth();
  }

  /**
   * Return the x coordinate
   * 
   * @return The x coordinate.
   */
  public float getX() {
    return this.x;
  }

  /**
   * Set the x coordinate
   * 
   * @param x coordinate
   */
  public void setX(float x) {
    this.x = x;
  }

  /**
   * Return the y coordinate.
   * 
   * @return The y coordinate.
   */
  public float getY() {
    return this.y;
  }

  /**
   * Set the y coordinate.
   * 
   * @param y coordinate.
   */
  public void setY(float y) {
    previousY = this.y;
    this.y = y;
  }
  
  public float getPreviousY() {
    return previousY;
  }
  
  public void setPreviousY(float previousY) {
    this.previousY = previousY;
  }
  
  /**
   * Return the y velocity.
   * 
   * @return The y velocity
   */
  public float getYVelocity() {
    return yVelocity;
  }

  /**
   * Set the y velocity.
   * 
   * @param yVelocity The y velocity.
   */
  public void setYVelocity(float yVelocity) {
    this.yVelocity = yVelocity;
  }

  /**
   * Return the width of this harpoon.
   * 
   * @return The width in pixels.
   */
  public int getWidth() {
    return this.harpoonWidth;
  }

  /**
   * Return the height of this harpoon.
   * 
   * @return The height in pixels.
   */
  public int getHeight() {
    return this.harpoonHeight;
  }

  /**
   * Return whether harpoon was obtained.
   * 
   * @return powerupObtained
   */
  public boolean powerupObtained() {
    return this.powerupObtained;
  }

  /**
   * Power up obtained. Set pwerupObtained to true.
   */
  public void obtainedPowerup() {
    this.powerupObtained = true;
  }

  /**
   * Used the power up. Set powerupObtained to false.
   */
  public void usedPowerup() {
    this.powerupObtained = false;
  }

  /**
   * Return whether the harpoon was launched.
   * 
   * @return whether harpoon was launched.
   */
  public boolean getLaunched() {
    return this.launched;
  }

  /**
   * Set whether this harpoon is launched.
   * 
   * @param launched whether harpoon was launched
   */
  public void setLaunched(boolean launched) {
    this.launched = launched;
  }

  /**
   * For when the user got the powerup and they clicked below the paddle.
   * 
   * @param paddle
   */
  public void appear(Paddle paddle) {
    this.launched = true;
    usedPowerup();
    this.x = paddle.getX() + (paddle.getWidth() / 2) - (this.harpoonWidth / 2);
    this.y = paddle.getY() - (5 + this.harpoonHeight);
    this.yVelocity = 20;
  }

  /**
   * For when the harpoon either goes off the screen or hits a shark.
   */
  public void disappear() {
    this.lastUpdateTime = -1;
    this.launched = false;
    this.x = -50;
    this.y = -50;
    this.yVelocity = 0;
  }

  /**
   * Draw the ball to the canvas.
   * 
   * @param canvas
   */
  public void draw(Canvas canvas) {
    canvas.drawBitmap(bitmap, x, y, null);
  }

  /**
   * Updates the harpoon position only if the harpoon has been launched.
   * 
   * @param shark
   */
  public void updatePosition(Shark blueShark, Shark orangeShark,
      SharkDeath blueSharkDeath, SharkDeath orangeSharkDeath) {
    if (this.launched) {
      if (this.y + this.harpoonHeight <= 0) {
        disappear();
        return;
      }

      long currentTime = System.currentTimeMillis();
      if (this.lastUpdateTime < 0) {
        this.lastUpdateTime = currentTime;
        return;
      }

      long elapsedTime = currentTime - this.lastUpdateTime;
      this.lastUpdateTime = currentTime;

      previousY = y;
      this.y = this.y - this.yVelocity * elapsedTime / 1000 * this.pixelsPerMeter;

      if (blueShark != null && blueShark.isCloseTo(this)) {
        if (blueShark.hitShark(this)) {
          blueSharkDeath.startDying(blueShark);
          blueShark.killed();
          disappear();
        }
      }
      if (orangeShark != null && orangeShark.isCloseTo(this)) {
        if (orangeShark.hitShark(this)) {
          orangeSharkDeath.startDying(orangeShark);
          orangeShark.killed();
          disappear();
        }
      }
    }
  }

}
